import { _decorator, Button, color, instantiate, Label, NodePool, tween, Tween, UITransform, Vec3, Widget } from 'cc';
import { BaseUI } from '../../../../frame/component/ui.base';
import GameDC from '../../../data/data.game.center';
import ConfManager from '../../../manager/config.manager';
import DataManager from '../../../manager/data.manager';
import { Float } from '../float';
import { Popup } from '../pop-up';
const { ccclass, property } = _decorator;

@ccclass('Achieve')
export class Achieve extends BaseUI{
	private ui_top: UITransform;
	private ui_fine: UITransform;
	private ui_view_container: UITransform;
	private ui_list_container: UITransform;
	private lbl_diamond: Label;
	private icon_diamond: UITransform;

	private va_top: mtec.cc.VecAssist;
	private va_fine: mtec.cc.VecAssist;
	private va_view_container: mtec.cc.VecAssist;
	private va_list_container: mtec.cc.VecAssist;

	private curr_view: 'master'|'round'|'remove';
	private ui_status: 'enter' | 'leave';

	protected initAfterOnLoad(){
		this.init();
	}

	protected start(){
		this.adaptUI();
		this.initUIStatus();

		this.node.active = false;
	}

	protected _click_event_: { [name: string]: (this: Achieve, button: Button) => void; } = {
		master(){
			this.changeView('master');
		},
		round(){
			this.changeView('round');
		},
		remove(){
			this.changeView('remove');
		},
		close(btn){
			btn.interactable = false;
			GameDC.Trigger.UIAchieve = false;
		},
		diamond(){
			if(GameDC.Status.home_ui_btn_lock){
				return void 0;
			}
			GameDC.Status.home_ui_btn_lock = true;

			Popup.Diamond().then(()=>GameDC.Status.home_ui_btn_lock = false);
		}
	}

	protected listening(){

		let diamond_obj = {value: 0};

		((o: any, lbl: Label)=>{
			let value: number;
			Reflect.deleteProperty(o, 'value');
			Reflect.defineProperty(o, 'value', {
				get(){
					return value;
				},
				set(v){
					value = v;
					lbl.string = Math.round(v).toString();
				}
			});
		})(diamond_obj, this.lbl_diamond);
		diamond_obj.value = GameDC.User.diamond;

		let list = [
			this.follow(GameDC.Trigger, 'UIAchieve', (o, v)=>this.onUIAchieveTrigger(v, o), false),
			this.follow(GameDC.Trigger, 'FLOAT_DIAMOND', (o, v)=>this.onFloatDiamondTrigger(v), false),
			this.follow(GameDC.User, 'diamond', (o, v)=>{
				Tween.stopAllByTarget(diamond_obj);
				tween(diamond_obj).to(0.8, {value: v}).start();
			}, false),
			this.follow(GameDC.Cache, 'round_curr', (o, v)=>this.refreshRoundHint()),
			this.follow(GameDC.Cache, 'remove_count', (o, v)=>{
				this.refreshRemoveHint();
				this.refreshMasterHint();
			}),
			this.follow(GameDC.User, 'task_round', (o, v)=>this.refreshRoundHint()),
			this.follow(GameDC.User, 'task_remove', (o, v)=>this.refreshRemoveHint()),
			this.follow(GameDC.User, 'master_free_level', (o, v)=>this.refreshMasterHint()),
		];

		DataManager.UserInfoSynced.then(()=>{
			if(GameDC.User.master){
				return void 0;
			}

			let reg = this.follow(GameDC.User, 'master', (o, active)=>{
				if(active){
					this.cancel(reg);
					this.tryReapMaster();
				}
			}, false);
		})

		return list;
	}

	private init(){
		this.ui_top = this.node.getChildByName('top').getComponent(UITransform);
		this.ui_fine = this.node.getChildByName('background-fine').getComponent(UITransform);
		this.ui_view_container = this.node.getChildByName('view-container').getComponent(UITransform);
		this.ui_list_container = this.ui_view_container.node.getChildByName('list-container').getComponent(UITransform);
		let node_diamond = this.ui_top.node.getChildByName('diamond');
		this.lbl_diamond = node_diamond.getChildByName('lbl-value').getComponent(Label);
		this.icon_diamond = node_diamond.getChildByName('icon').getComponent(UITransform);

		this.va_top = new mtec.cc.VecAssist(this.ui_top.node);
		this.va_fine = new mtec.cc.VecAssist(this.ui_fine.node);
		this.va_view_container = new mtec.cc.VecAssist(this.ui_view_container.node);
		this.va_list_container = new mtec.cc.VecAssist(this.ui_list_container.node);

		this.ui_list_container.node.children.forEach(n=>n.active=false);
	}

	private adaptUI(){
		let wgt = this.node.getComponent(Widget);
		if(!wgt){
			wgt = this.node.addComponent(Widget);
			[wgt.isAlignTop, wgt.isAlignBottom, wgt.isAlignLeft, wgt.isAlignRight] = [true, true, true, true];
			[wgt.isAbsoluteTop, wgt.isAbsoluteBottom, wgt.isAbsoluteLeft, wgt.isAbsoluteRight] = [true, true, true, true];
			[wgt.top, wgt.bottom, wgt.left, wgt.right] = [0, 0, 0, 0];
		}
		wgt.updateAlignment();

		let ui_main = this.node.getComponent(UITransform);

		this.ui_view_container.setContentSize(ui_main.width, ui_main.height - (mtec.cc.is_long_screen ? 502 : 402));
		let temp_uitrans = this.ui_view_container.node.getChildByName('background').getComponent(UITransform);
		temp_uitrans.setContentSize(ui_main.width, ui_main.height - (mtec.cc.is_long_screen ? 502 : 402) - 83);
		this.ui_list_container.setContentSize(ui_main.width * 3, ui_main.height - (mtec.cc.is_long_screen ? 502 : 402) - 105);

		this.ui_list_container.node.children.forEach(n=>n.active=true);
	}

	private initUIStatus(){
		this.va_top.getPosition('center', 'top');
		this.va_fine.getPosition('over_right', 'top');
		this.va_view_container.getPosition('center', 'over_bottom');

		if(mtec.cc.is_long_screen){
			this.va_top.vec.add3f(0, -100, 0);
			this.va_fine.vec.add3f(0, -100, 0);
		}

		this.ui_top.node.setPosition(this.va_top.vec);
		this.ui_fine.node.setPosition(this.va_fine.vec);
		this.ui_view_container.node.setPosition(this.va_view_container.vec);

		let ui_tags = this.ui_view_container.node.getChildByName('tags').getComponent(UITransform);
		let va_tags = new mtec.cc.VecAssist(ui_tags.node);

		va_tags.getPosition('center', 'top');
		ui_tags.node.setPosition(va_tags.vec);
		this.changeView('master');

		(<const>[
			['master', 'MASTER PASS'],
			['round', 'Passing Tasks'],
			['remove', 'Elimination'],
		]).forEach(([name, text])=>{
			ui_tags.node.getChildByName('lbl-'+name+'-light').getComponent(Label).string = text;
			ui_tags.node.getChildByName('lbl-'+name+'-dark').getComponent(Label).string = text;
		});
	}

	private changeView(view_name: 'master'|'round'|'remove', force?: boolean){
		if(!force && view_name===this.curr_view){
			return void 0;
		}
		this.curr_view = view_name;

		['master', 'round', 'remove'].forEach(name=>{
			let btn = this.__btn_map__.get(name);
			let curr = name===view_name;
			btn.interactable = !curr;
			btn.node.getChildByName('light').active = curr;
			btn.node.getChildByName('dark').active = !curr;
			btn.node.parent.getChildByName('lbl-'+name+'-dark').active = !curr;
			btn.node.parent.getChildByName('lbl-'+name+'-light').active = curr;
		});

		switch(view_name){
			case 'master':
				this.va_list_container.getPosition('left', 'bottom');
				break;
			case 'round':
				this.va_list_container.getPosition('center', 'bottom');
				break;
			case 'remove':
				this.va_list_container.getPosition('right', 'bottom');
				break;
		}

		Tween.stopAllByTarget(this.ui_list_container.node);
		this.ui_list_container.node.children.forEach(n=>n.active=true);
		tween(this.ui_list_container.node)
		.to(0.5, {position: this.va_list_container.vec}, {easing: 'cubicOut'})
		.call(()=>{
			this.ui_list_container.node.children.forEach(n=>n.active = n.name===view_name);
			this.tryReapMaster();
		}).start();
	}

	private onUIAchieveTrigger(show: boolean, ov: boolean){
		if(show){
			this.enter();
		}else{
			this.leave();
		}
	}

	private enter(){
		if(this.ui_status=='enter'){
			return void 0;
		}
		this.ui_status = 'enter';
		this.node.active = true;

		this.__btn_map__.forEach(btn=>btn.interactable = true);
		this.__btn_map__.get('close').node.active = true;

		this.va_top.getPosition('center', 'top');
		this.va_fine.getPosition('center', 'top');
		this.va_view_container.getPosition('center', 'bottom');

		if(mtec.cc.is_long_screen){
			this.va_top.vec.add3f(0, -100, 0);
			this.va_fine.vec.add3f(0, -100, 0);
		}

		this.changeView(this.curr_view, true);

		[this.ui_fine, this.ui_view_container].forEach(ui=>Tween.stopAllByTarget(ui.node));

		this.ui_top.node.setPosition(this.va_top.vec);
		this.ui_top.node.active = true;

		tween(this.ui_view_container.node).to(0.5, {position: this.va_view_container.vec}, {easing: 'cubicOut'}).start();
		tween(this.ui_fine.node).delay(0.25).to(0.5, {position: this.va_fine.vec}, {easing: 'expoOut'}).start();
	}

	private leave(){
		if(this.ui_status=='leave'){
			return void 0;
		}
		this.ui_status = 'leave';

		this.__btn_map__.forEach(btn=>btn.interactable = false);
		this.__btn_map__.get('close').node.active = false;

		this.va_fine.getPosition('over_left', 'top');
		this.va_view_container.getPosition('center', 'over_bottom');

		this.va_fine.vec.add3f(-100, 0, 0);
		if(mtec.cc.is_long_screen){
			this.va_fine.vec.add3f(0, -100, 0);
		}

		[this.ui_fine, this.ui_view_container].forEach(ui=>Tween.stopAllByTarget(ui.node));

		tween(this.ui_fine.node).to(0.5, {position: this.va_fine.vec}, {easing: 'expoOut'}).start();
		tween(this.ui_view_container.node).delay(0.25).to(0.5, {position: this.va_view_container.vec}, {easing: 'cubicOut'})
		.call(()=>this.onLeaved()).start();
	}

	private onLeaved(){
		this.va_fine.getPosition('over_right', 'top');
		if(mtec.cc.is_long_screen){
			this.va_fine.vec.add3f(0, -100, 0);
		}

		this.ui_fine.node.setPosition(this.va_fine.vec);

		this.node.active = false;
		this.ui_top.node.active = false;
	}

	private async tryReapMaster(){
		if(this.ui_status!='enter' || this.curr_view!=='master'){
			return void 0;
		}

		await DataManager.ConfigInited;

		let reap_info = DataManager.getMasterReap();
		if(!(reap_info.map.size>0)){
			return void 0;
		}

		mtec.delay(0.5, ()=>{
			if(this.curr_view!=='master'){
				return void 0;
			}
			reap_info = DataManager.reapMaster();

			Popup.Congratulation(Array.from(reap_info.map))
			.then(()=>{
				if(reap_info.diamond>0){
					DataManager.floatDiamond(reap_info.diamond, mtec.cc.canvas.node.position);
				}
			});
		});
	}

	private lbl_diamond_color_dr = color(99, 243, 44);
	private lbl_diamond_color_dd = color(251, 66, 69);
	private lbl_diamond_offset = new Vec3(0, 40, 0);
	private lbl_diamond_pool = new NodePool();
	private async onFloatDiamondTrigger(num: number){
		if(this.ui_status!=='enter'){
			return void 0;
		}

		let vec = DataManager.diamond_float_from;
		if(!GameDC.Trigger.UIHome && num>0 && vec){
			await Float.Reap(this.icon_diamond.node, mtec.number.random(6, 8), vec);
		}

		let lbl = (this.lbl_diamond_pool.get() ?? instantiate(this.lbl_diamond.node)).getComponent(Label);
		lbl.color = num>0 ? this.lbl_diamond_color_dr : this.lbl_diamond_color_dd;
		lbl.string = num>0 ? `+${num}` : `${num}`;
		lbl.node.setScale(0.8, 0.8, 1);
		lbl.node.active = true;
		lbl.node.setParent(this.lbl_diamond.node.parent);
		lbl.node.setPosition(this.lbl_diamond.node.position);

		tween(lbl.node).by(0.6, {position: this.lbl_diamond_offset}).delay(0.6)
		.call(()=>this.lbl_diamond_pool.put(lbl.node)).start();
	}

	private async refreshMasterHint(){
		await DataManager.ConfigInited;

		let list = ConfManager.masterList;
		let idx = -1;
		while(list[idx+1].remove_total<=DataManager.master_remove && idx<list.length-1){
			idx++;
		}

		let data = list[idx];
		if(data){
			this.__btn_map__.get('master').node.getChildByName('hint').active = GameDC.User.master_free_level<data.level;
		}else{
			this.__btn_map__.get('master').node.getChildByName('hint').active = false;
		}
	}

	private async refreshRoundHint(){
		await DataManager.ConfigInited;

		let list = ConfManager.otherConf.taskRound;
		let round = GameDC.Cache.round_curr-1;
		let idx = -1;
		while(list[idx+1].round<=round && idx<list.length-1){
			idx++;
		}
		let task = list[idx];
		if(task){
			this.__btn_map__.get('round').node.getChildByName('hint').active = !GameDC.checkTask('round', task.round);
		}else{
			this.__btn_map__.get('round').node.getChildByName('hint').active = false;
		}
	}

	private async refreshRemoveHint(){
		await DataManager.ConfigInited;

		let list = ConfManager.otherConf.taskRemove;
		let idx = -1;
		while(list[idx+1].count<=GameDC.Cache.remove_count && idx<list.length-1){
			idx++;
		}
		let task = list[idx];
		if(task){
			this.__btn_map__.get('remove').node.getChildByName('hint').active = !GameDC.checkTask('remove', task.count);
		}else{
			this.__btn_map__.get('remove').node.getChildByName('hint').active = false;
		}
	}
}

